home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / t3_1 / doc.lha / documentation / manual / environment.ms < prev    next >
Text File  |  1987-06-30  |  14KB  |  391 lines

  1. @part[ENVIRONMENT, root "TMAN.MSS"]     @Comment{-*-System:TMAN-*-}
  2. @chap[Environments]
  3. @label[EnvironmentsChapter]     @Comment{ref: semantics chapter}
  4.  
  5.  
  6. @section[Environments and contours]
  7. @label[environments]
  8.  
  9. @iix[Environments] are associations between @iix[identifiers] (variable
  10. names) and @iix[values].  One such association between an identifier
  11. and a value is called a @iixs[binding].  In general, environments
  12. are created implicitly, for example, on entering @tc[LAMBDA]-bodies.
  13. @index[variables]
  14.  
  15. @dc{ However, environments may be obtained as objects via the @tc[LOCALE]
  16. special form; see section @ref[LocaleSection]. }
  17. @dc{ -- Explain the term @i[variable]. }
  18.  
  19. Environments are organized hierarchically into @iix[contours].  Each
  20. contour augments an @qu"outer" environment, providing bindings for a few
  21. identifiers.  These bindings are in effect in the body of the
  22. expression which introduces the contour.  The portion of a program in which
  23. a binding is in effect is known as the variable's @iix[scope].
  24.  
  25. For example:
  26.   @begin[ProgramExample]
  27. (BLOCK
  28.  (LIST 'A 'B)
  29.  ...
  30.  (LAMBDA (A B C)
  31.    ...                  ; [1]
  32.    (LAMBDA (D E)
  33.      ...                ; [2]
  34.      )
  35.    ...                  ; [3]
  36.    (LAMBDA (A F G)
  37.      ...                ; [4]
  38.      )
  39.    ...)
  40.  ...)
  41.   @end[ProgramExample]
  42. Each @tc[LAMBDA] introduces a new contour.  This code presumably occurs in
  43. an outermost environment in which the variable @tc[LIST] is bound.
  44. (The values of @tc[BLOCK] and @tc[LAMBDA] are not in question here;
  45. they are reserved words, and their bindings as variables are irrelevant.)
  46. At point @tc<[1]> in the program, a new environment is in effect
  47. which now has bindings for @tc[A], @tc[B], and @tc[C], as well as for
  48. any variables known in the outer environment.  At @tc<[2]>,
  49. @tc[D] and @tc[E] also have values.  @tc<[3]> is in the
  50. scope of @tc[A], @tc[B], and @tc[C] but not in the scope of
  51. @tc[D] and @tc[E].  Finally, the outer binding
  52. of any given identifier is @i[shadowed]@index[shadowing]
  53. by inner bindings of that identifier;
  54. an occurrence of the identifier @tc[A]
  55. appearing at @tc<[4]> refers not to the outer @tc[A]
  56. but to the inner one, because the inner one shadows the outer.
  57.  
  58. There are two kinds of contours, known as @i[lambda-contours] and
  59. @i[locales].  Lambda-contours are introduced by many special forms,
  60. such as @tc[LAMBDA], @tc[LET], and @tc[LABELS].  Locales are
  61. introduced by @tc[LOCALE] special forms.
  62.  
  63.  
  64. @section[Local variables]
  65.  
  66. @info[NOTES="Special form"]
  67. @desc[@el[](LET @i[specs] . @i[body]) @yl[] @i[value-of-body]]
  68. @tc[LET] provides a convenient syntax for introducing local bindings.
  69. Each @i[spec] should be a two-element list of the form @tc[(@i[variable
  70. value])].  The @i[value] expressions are all evaluated (in no particular
  71. order), then the
  72. @i[body] (an implicit block) is evaluated in an environment where the
  73. @i[variables] are bound to those values.  The value of @i[body] is
  74. yielded.
  75. @begin[ProgramExample]
  76. (LET ((X 2)) X)  @ev[]  2
  77.  
  78. (LET ((@i[var@-(1) val@-(1)]) (@i[var@-(2) val@-(2)]) ... (@i[var@-(n) val@-(n)])) . @i[body])
  79. @ce[] ((LAMBDA (@i[var@-(1) var@-(2) ... var@-(n)]) . @i[body]) @i[val@-(1) val@-(2) ... val@-(n)])
  80. @end[ProgramExample]
  81.  
  82. See also @tc[DESTRUCTURE] (page @PageRef[destructure]).
  83. @EndDesc[LET]
  84.  
  85. @info[NOTES="Special form"]
  86. @desc[(LET* @i[specs] . @i[body]) @yl[] @i[value-of-body]]
  87. @tc[LET*] is like @tc[LET], except that the binding of variables to
  88. values is done sequentially, so that the second binding
  89. is done in an environment in which the first binding has already occurred,
  90. etc.  In a @tc[LET]-expression, all the bindings are done in one
  91. environment.
  92.  
  93. For example,
  94. suppose the variable @tc[A] is already bound to @tc[10] when
  95. the expression @wt[(LET ((A 20) (B A)) B)] is evaluated.  The
  96. result is @tc[10], not @tc[20], because @tc[B] is bound to
  97. @tc[A]'s value in the outer environment.  In contrast,
  98. @wt[(LET* ((A 20) (B A)) B)] evaluates to @tc[20].
  99.  
  100. @begin[ProgramExample]
  101. (LET* ((@i[var@-[1] val@-[1]]) (@i[var@-[2] val@-[2]]) ... (@i[var@-[n] val@-[n]])) . @i[body])
  102.   @ce[]
  103. (LET ((@i[var@-[1] val@-[1]]))
  104.   (LET ((@i[var@-[2] val@-[2]]))
  105.        ...
  106.        (LET ((@i[var@-[n] val@-[n]])) . @i[body])...))
  107.   @ce[] 
  108. ((LAMBDA (@i[var@-[1]])
  109.    ((LAMBDA (@I[var@-[2]])
  110.        ...
  111.        ((LAMBDA (@I[var@-[n]]) . @i[body])
  112.         @I[val@-[n]]) ...)
  113.     @i[val@-[2]]))
  114.  @i[val@-[1]])
  115. @end[ProgramExample]
  116. @EndDesc[LET*]
  117.  
  118.  
  119. @AnEquivE[Tfn="LABELS",Efn="LABEL"]
  120. @info[NOTES="Special form"]
  121. @desc[@el[](LABELS @i[specs] . @i[body]) @yl[] @i[value-of-body]]
  122. @tc[LABELS] is useful for defining local procedures that may be
  123. mutually recursive.
  124. Each @i[spec] should be of the form
  125. @wt[(@i[variable value])].
  126. The @i[value]-expressions are evaluated (in no particular order), and
  127. the @i[body] is evaluated in an environment
  128. where all the @i[variables] are bound to those values.
  129. However, @tc[LABELS] differs from @tc[LET]
  130. in that
  131. the bindings of the @i[variables] are already in effect (scope) before the
  132. @i[value]-expressions are evaluated, so that the
  133. @i[value]-expressions can refer to any of the @i[variables],
  134. including the ones to which they themselves will be bound (thus permitting
  135. local recursive procedures).
  136.  
  137. Each @i[spec] may alternatively have the form
  138. @begin[ProgramExample]
  139. @wt[((@i[variable] . @i[argument-vars]) . @i[body])].
  140. @end[ProgramExample]
  141. This is equivalent to
  142. @begin[ProgramExample]
  143. @wt[(@i[variable] (LAMBDA @i[argument-vars] . @i[body]))]
  144. @end[ProgramExample]
  145. This is intended to parallel the syntax for @tc[DEFINE] (see page
  146. @PageRef(define)).
  147.  
  148. In the following example, note that @tc[REV-1] is bound to a value that
  149. refers to @tc[REV-1].
  150. @begin[ProgramExample]
  151. @tabclear
  152. (DEFINE (REVERSE L)
  153.   (LABELS (((REV-1 L RESULT-SO-FAR)
  154.             (COND ((NULL? L) RESULT-SO-FAR)
  155.                   (ELSE
  156.                     (REV-1 (CDR L)
  157.                            (CONS (CAR L) RESULT-SO-FAR))))))
  158.     (REV-1 L '())))
  159. @tabclear
  160. @end[ProgramExample]
  161.  
  162. As an extension to the dialect of SCHEME described in
  163. @cite[STEELE78REV], @tau[] does not restrict the @i[value] expressions
  164. to be @tc[LAMBDA]-expressions.
  165. However, the values of the @i[variables]
  166. are not defined until @i[body] is evaluated; i.e., they should
  167. not be used in the @i[value]-expressions.  For example,
  168. @teg[(LABELS ((A B) (B 1)) . @i[body])]
  169. is ill-formed;
  170. at the point when the expressions @tc[B] and @tc[1] are being evaluated,
  171. the variable @tc[B] is bound,
  172. but will have an undefined value.  Consequently, @tc[A] will have an undefined
  173. value.  By contrast, in the well-formed expression
  174.  
  175. @begin[teg]
  176. (LABELS ((A (LAMBDA (X) (+ X B))) (B 1)) . @i[body])@r[,]
  177. @end[teg]
  178.  
  179. which can also be written
  180.  
  181. @begin[teg]
  182. (LABELS (((A X) (+ X B)) (B 1)) . @i[body])@r[,]
  183. @end[teg]
  184.  
  185. the value of @tc[B] is not used before @i[body] is evaluated.
  186. The @tc[LAMBDA]-expression evaluates
  187. to a @i[closure] that includes @tc[B].  By the time @tc[A] (the closure)
  188. is called, @tc[B] will have a value.
  189.  
  190. @tc[LABELS] cannot easily be described in terms of @tc[LAMBDA].
  191. However, it can be described in terms of @tc[LAMBDA] and @tc[SET].
  192. (@tc[SET] performs side-effects on bindings; see page @pageref[SET].)
  193. This is misleading because @tc[LABELS] should not be thought of as a
  194. side-effecting operator.  @dc{?}
  195.   @begin[TEG]
  196. (LABELS ((@i[var@-[1]] @i[val@-[1]])
  197.          (@i[var@-[2]] @i[val@-[2]])
  198.          ...
  199.          (@i[var@-[n]] @i[val@-[n]]))
  200.   . @i[body])
  201.    @ce[]
  202. (LET ((@i[var@-[1]] (UNDEFINED-VALUE))
  203.       (@i[var@-[2]] (UNDEFINED-VALUE))
  204.       ...
  205.       (@i[var@-[n]] (UNDEFINED-VALUE)))
  206.   (SET @i[var@-[1]] @i[val@-[1]])
  207.   (SET @i[var@-[2]] @i[val@-[2]])
  208.   ...
  209.   (SET @i[var@-[n]] @i[val@-[n]])
  210.   . @i[body])
  211.   @end[TEG]
  212. This equivalence is overly concrete in that the order of evaluation of
  213. the @i[val@-[i]] expressions, and the sequence in which the
  214. variables are given their values, is not defined.
  215. @EndDesc[LABELS]
  216.  
  217.  
  218. @section[Locales]
  219. @label[LocaleSection]   @Comment{ref: above; intro to env chapter}
  220.  
  221. @i[Locales] serve two purposes.  First, they provide an incremental or
  222. declarative syntax for creating variable bindings in a contour.  Second,
  223. they provide access to environments as objects which can be dynamically
  224. manipulated.  The term @iixs[locale] is used to mean both the kind of
  225. contour introduced by a @tc[LOCALE]-expression, and the object which
  226. represents the environment.
  227.  
  228. There are no global variables in @Tau[]; all variables are lexically
  229. bound in some contour.  Locales play the role of what is known in other
  230. Lisp and Scheme dialects as the global environment.
  231.  
  232. @info[NOTES="Special form"]
  233. @desc[(LOCALE @i[variable . body]) @yl[] @i[value-of-body]]
  234. Introduces a locale and evaluates @i[body] (an implicit block) in it.
  235. The value of the @tc[LOCALE] expression is that of @i[body]'s last form.
  236. Within @i[body], @i[variable] is bound to the locale.
  237. If @i[variable] is @tc[()], then the locale is not accessible as an object.
  238.  
  239.     @BeginInset[Bugs:]
  240.     @Timp[] 2.7 implements @tc[LOCALE] incorrectly in several different
  241.     ways.  First, locales are created permanently; once created, a
  242.     locale's storage is never reclaimed, even if it is completely
  243.     inaccessible.  This means that for now they should only be used
  244.     to create environments statically, not, for example, in a loop,
  245.     or whenever some procedure is called.
  246.  
  247.     Second, forward references to shadowed variables don't work.
  248.     For example:
  249.   @begin[ProgramExample]
  250. (LET ((A 10)) (LOCALE () (DEFINE (F) A) (DEFINE A 20) (F)))
  251.   @end[ProgramExample]
  252.     yields @tc[10] instead of @tc[20].
  253.  
  254.     Third, TC doesn't handle them very well; it just lets @tc[EVAL] interpret
  255.     the body of the locale.  For all these reasons, it is preferable
  256.     to use @tc[MAKE-LOCALE] (page @pageref[MAKE-LOCALE]) instead
  257.     of @tc[LOCALE] wherever possible.
  258.     @EndInset[]
  259. @EndDesc[LOCALE]
  260.  
  261. @AnEquivE[Tfn="DEFINE",Efn="DE"]
  262. @AnEquivE[Tfn="DEFINE",Efn="DEFVAR"]
  263. @info[NOTES="Special form",EQUIV="DEFUN"]
  264. @descN[
  265. F1="@el[](DEFINE @i[variable] @i[value]) @yl[] @i[undefined]",
  266. FN1="DEFINE",
  267. F2="@el[](DEFINE (@i[variable] . @i[arguments]) . @i[body]) @yl[] @i[undefined]"
  268. ]
  269. @tc[DEFINE] creates a binding for @i[variable]
  270. in the lexically innermost locale in which the @tc[DEFINE] expression occurs.
  271. The variable is given @i[value] as its value.
  272.  
  273. The second @tc[DEFINE] syntax is for defining procedures.
  274.   @begin[TEG]
  275. (DEFINE (@i[variable] . @i[arguments]) . @i[body])
  276.   @end[TEG]
  277. is equivalent to
  278.   @begin[TEG]
  279. (DEFINE @i[variable] (LAMBDA @i[arguments] . @i[body]))
  280.   @end[TEG]
  281. For example:
  282.   @begin[ProgramExample]
  283. (DEFINE (F X) (LIST X 2))    @ce[]  (DEFINE F (LAMBDA (X) (LIST X 2)))
  284. (DEFINE (F . X) (LIST X 2))  @ce[]  (DEFINE F (LAMBDA X (LIST X 2)))
  285.   @end[ProgramExample]
  286. @EndDescN[]
  287.  
  288. @info[NOTES="Special form"]
  289. @Desc[(LSET @i[variable value]) @yl[] @i[value]]
  290. @tc[LSET] is identical to @tc[DEFINE] except that the procedure
  291. definition syntax is not permitted, and the variable is declared to be
  292. alterable.  Variables bound by @tc[DEFINE] may not be altered
  293. with @tc[SET]; variables bound by @tc[LSET] may be.
  294. See @tc[SET], page @pageref[SET].
  295. @EndDesc[LSET]
  296.  
  297. Any @tc[LOCALE]-expression whose @i[variable] position is @tc[()]
  298. may be rewritten as an expression
  299. involving only @tc[LET] or @tc[LABELS].  In this case the use of
  300. @tc[LOCALE] is simply a notational difference; using @tc[LOCALE] instead
  301. of @tc[LET] or @tc[LABELS] may make code easier or harder to read and
  302. manipulate.
  303.  
  304.   @begin[TEG]
  305. (LOCALE ()
  306.   (DEFINE FOO ...)
  307.   (DEFINE BAR ...)
  308.   ...)
  309.    @ce[]
  310. (LABELS ((FOO ...)
  311.          (BAR ...))
  312.   ...)
  313.   @end[TEG]
  314.  
  315. This transformation may not be possible if the @tc[LOCALE]-expression
  316. binds a variable to the locale; in this case new bindings may be added
  317. as a result of calls to @tc[*DEFINE] or @tc[*LSET] (see below), and
  318. there is no way to anticipate what variables should be bound by the
  319. @tc[LABELS] or @tc[LET] expression.
  320.  
  321. References in a @tc[LOCALE] body to variables bound later
  322. on in that locale are undefined.  For example,
  323.  
  324.   @begin[TEG]
  325. (LET ((A 10)) (LOCALE () (LET ((B A)) (DEFINE A 20) B)))
  326.   @end[TEG]
  327.  
  328. has an undefined effect; it may yield @tc[10] or @tc[20],
  329. or it may signal an error.
  330.     @BeginInset[Rationale:]
  331.     The undefinedness of forward references permits implementations
  332.     flexibility in dealing with the declarative nature of @tc[DEFINE]
  333.     and @tc[LSET].  New bindings may be registered either when
  334.     encountered during evaluation, to simplify evaluation, or may
  335.     be registered during a pre-processing (compilation) phase, to
  336.     permit compilation to a more efficient representation.
  337.     @EndInset[]
  338.  
  339. @desc[(MAKE-LOCALE @i[superior-locale] @i[identification]) @yl[] @i[locale]]
  340. Creates a locale inferior to @i[superior-locale].  @i[Identification]
  341. may be any object, and is used only for debugging purposes.
  342.   @begin[TEG]
  343. (DEFINE *FOO-ENV* (MAKE-LOCALE *STANDARD-ENV* '*FOO-ENV*))
  344.   @end[TEG]
  345. @enddesc[MAKE-LOCALE]
  346.  
  347. @desc[(MAKE-EMPTY-LOCALE @i[identification]) @yl[] @i[locale]]
  348. Creates a locale containing no bindings whatsoever.
  349. @enddesc[MAKE-EMPTY-LOCALE]
  350.  
  351. @info[NOTES="Type predicate"]
  352. @desc[(LOCALE? @i[object]) @yl[] @i[boolean]]
  353. Returns true if @i[object] is a locale.
  354. @enddesc[LOCALE?]
  355.  
  356.  
  357. @section[Non-local reference]
  358.  
  359. @info[notes="Settable"]
  360. @desc[(*VALUE @i[locale identifier]) @yl[] @i[object]]
  361. Accesses the value of @i[identifier] in @i[locale].
  362. If @i[identifier] has no value in @i[locale], then
  363. the effect of the call to @tc[*VALUE] is undefined.
  364.   @begin[ProgramExample]
  365. (*VALUE *STANDARD-ENV* 'T)              @ev[]  @r[true]
  366. (*VALUE (LOCALE Z (DEFINE A 10) Z) 'A)  @ev[]  10
  367.   @end[ProgramExample]
  368. @EndDesc[*VALUE]
  369.  
  370. @desc[(*DEFINE @i[locale] @i[identifier] @i[value]) @yl[] @i[undefined]]
  371. Defines the value of @i[identifier] in @i[locale] to be @i[value].
  372. @enddesc[*DEFINE]
  373.  
  374. @desc[(*LSET @i[locale] @i[identifier] @i[value]) @yl[] @i[value]]
  375. Creates a binding for @i[identifier] in @i[locale] with initial
  376. value @i[value].
  377. @enddesc[*LSET]
  378.  
  379. @desc[(IMPORT @i[locale] . @i[variables]) @yl[] @i[undefined]]
  380. Locally defines @i[variables] to have the same values as their values
  381. in @i[locale].
  382.   @begin[ProgramExample]
  383. (IMPORT @i[locale] @i[var@-[1] var@-[2] ... var@-[n]])
  384.   @ce[]
  385. (BLOCK (DEFINE @i[var@-[1]] (*VALUE @i[locale] '@i[var@-[1]]))
  386.        (DEFINE @i[var@-[2]] (*VALUE @i[locale] '@i[var@-[2]]))
  387.        ...
  388.        (DEFINE @i[var@-[n]] (*VALUE @i[locale] '@i[var@-[n]])))
  389.   @end[ProgramExample]
  390. @enddesc[IMPORT]
  391.